package com.tk.exam.service.impl;

import com.github.pagehelper.PageInfo;
import com.tk.exam.dao.TkExamPaperDao;
import com.tk.exam.domain.TkQuestions;
import com.tk.exam.domain.TkRPaperQuestion;
import com.tk.exam.domain.TkStudentAnswer;
import com.tk.exam.mapper.TkExamPaperMapper;
import com.tk.exam.mapper.TkQuestionsMapper;
import com.tk.exam.mapper.TkStudentAnswerMapper;
import com.tk.exam.service.TkExamPaperService;
import com.tk.exam.vo.paper.*;
import com.tk.exam.utils.JsonUtils;
import com.tk.exam.utils.PageInfoExt;
import com.tk.exam.vo.question.resp.TkQuestion4CRespVo;
import com.tk.exam.vo.question.resp.TkQuestionDXRespVo;
import com.tk.exam.vo.question.resp.TkQuestionPDRespVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class TkExamPaperServiceImpl implements TkExamPaperService {
    //1:单选题,2:判断题,3:填空题,4:简答题,5:4C题
    public static final byte QUESTION_TYPE_DX=1;
    public static final byte QUESTION_TYPE_PD=2;
    public static final byte QUESTION_TYPE_TK=3;
    public static final byte QUESTION_TYPE_JS=4;
    public static final byte QUESTION_TYPE_FOURC=5;

    @Autowired
    private TkExamPaperDao tkExamPaperDao;
    @Autowired
    private TkQuestionsMapper tkQuestionsMapper;
    @Autowired
    private TkStudentAnswerMapper tkStudentAnswerMapper;
    @Autowired
    private TkExamPaperMapper tkExamPaperMapper;

    @Override
    public PageInfo<SearchPaperListResp> searchPaperListByPage() {
        return tkExamPaperDao.searchPaperListByPageWithPage();
    }

    @Override
    public PageInfo<ExamPaperVo> searchExamPapersWithPage() {
        return tkExamPaperDao.searchExamPapersWithPage();
    }

    @Override
    public List<ExamPaperVo> searchExamPapers() {
        return tkExamPaperMapper.searchExamPapers();
    }

    @Override
    public PageInfo<GetStuJudgeQAResp> getStuJudgeQA(GetStuQAReq req) {
        Map<String,Object> map=getPub(req,TkQuestionPDRespVo.class,QUESTION_TYPE_PD);
        List<TkQuestions> questions= (List<TkQuestions>) map.get("questions");
        Map<Integer,TkRPaperQuestion> paperQuestionMap= (Map<Integer, TkRPaperQuestion>) map.get("paperQuestionMap");
        Map<Integer,TkQuestionPDRespVo> queVoMaps= (Map<Integer, TkQuestionPDRespVo>) map.get("queVoMaps");
        Map<Integer, TkQuestionPDRespVo> aVoMaps= (Map<Integer, TkQuestionPDRespVo>) map.get("aVoMaps");
        PageInfo<TkRPaperQuestion> pageInfo= (PageInfo<TkRPaperQuestion>) map.get("pageInfo");
        //构建真正的返回结果list
        List<GetStuJudgeQAResp> resps=new Vector<>();
        questions.parallelStream().forEach(
                question->{
                    GetStuJudgeQAResp resp=new GetStuJudgeQAResp(paperQuestionMap.get(question.getId()),question,aVoMaps.get(question.getId()));
                    resps.add(resp);
                }
        );
        return new PageInfoExt(pageInfo,resps);
    }


    @Override
    public PageInfo<GetStuJSQAResp> getStuJSQA(GetStuQAReq req) {
        PageInfo<TkRPaperQuestion> pageInfo= tkExamPaperDao.getStuJudgeQAWithPage(req,QUESTION_TYPE_JS);
        return getJSTKPageInfo(pageInfo);
    }

    private PageInfo<GetStuJSQAResp> getJSTKPageInfo(PageInfo pageInfo){
        //paper和question的关联表记录list
        List<TkRPaperQuestion> paperQuestions=pageInfo.getList();
        //paperQuestion的map
        Map<Integer,TkRPaperQuestion> paperQuestionMap=paperQuestions.parallelStream().collect(Collectors.toConcurrentMap(TkRPaperQuestion::getQuestionId,paperQuestion->paperQuestion));
        //question的list
        List<TkQuestions> questions=tkQuestionsMapper.batchGetQuestionById(paperQuestions);

        List<GetStuJSQAResp> resps=new Vector<>();
        questions.parallelStream().forEach(
                question->{
                    GetStuJSQAResp resp=new GetStuJSQAResp(paperQuestionMap.get(question.getId()),question);
                    resps.add(resp);
                }
        );
        return new PageInfoExt(pageInfo,resps);
    }

    @Override
    public PageInfo<GetStuJSQAResp> getStuTKQA(GetStuQAReq req) {
        PageInfo<TkRPaperQuestion> pageInfo= tkExamPaperDao.getStuJudgeQAWithPage(req,QUESTION_TYPE_TK);
        return getJSTKPageInfo(pageInfo);
    }

    @Override
    public PageInfo<GetStuDXResp> getStuDXQA(GetStuQAReq req) {
        Map<String,Object> map=getPub(req,TkQuestionDXRespVo.class,QUESTION_TYPE_DX);
        List<TkQuestions> questions= (List<TkQuestions>) map.get("questions");
        Map<Integer,TkRPaperQuestion> paperQuestionMap= (Map<Integer, TkRPaperQuestion>) map.get("paperQuestionMap");
        Map<Integer,TkQuestionDXRespVo> queVoMaps= (Map<Integer, TkQuestionDXRespVo>) map.get("queVoMaps");
        Map<Integer, TkQuestionDXRespVo> aVoMaps= (Map<Integer, TkQuestionDXRespVo>) map.get("aVoMaps");
        PageInfo<TkRPaperQuestion> pageInfo= (PageInfo<TkRPaperQuestion>) map.get("pageInfo");

        //构建真正的返回结果list
        List<GetStuDXResp> resps=new Vector<>();
        questions.parallelStream().forEach(
                question->{
                    GetStuDXResp resp=new GetStuDXResp(paperQuestionMap.get(question.getId()),queVoMaps.get(question.getId()),aVoMaps.get(question.getId()));
                    resps.add(resp);
                }
        );
        return new PageInfoExt(pageInfo,resps);
    }

    public <T> Map<String,Object> getPub(GetStuQAReq req,Class<T> clazz,byte quesType){
        Map<String,Object> map=new HashMap<>();
        PageInfo<TkRPaperQuestion> pageInfo= tkExamPaperDao.getStuJudgeQAWithPage(req,quesType);
        //paper和question的关联表记录list
        List<TkRPaperQuestion> paperQuestions = pageInfo.getList();
        //paperQuestion的map
        Map<Integer,TkRPaperQuestion> paperQuestionMap=paperQuestions.parallelStream().collect(Collectors.toConcurrentMap(TkRPaperQuestion::getQuestionId,paperQuestion->paperQuestion));
        //question的list
        List<TkQuestions> questions=tkQuestionsMapper.batchGetQuestionById(pageInfo.getList());

        Map<Integer,T> queVoMaps=questions.parallelStream().collect(Collectors.toConcurrentMap(TkQuestions::getId,question->{return JsonUtils.string2Object(question.getQuesContent(),clazz);}));

        List<Integer> questionIds = new Vector<Integer>();
        paperQuestions.parallelStream().forEach(
                paperQuestion ->questionIds.add(paperQuestion.getQuestionId())
        );
        //answer的list
        List<TkStudentAnswer> answers=tkStudentAnswerMapper.batchGetAnswerByIdAndStuId(questionIds,req.getStuId(),req.getExamId());
        //answer的map
        Map<Integer, T> aVoMaps=answers.parallelStream().collect(Collectors.toConcurrentMap(TkStudentAnswer::getQuestionId, answer->{return JsonUtils.string2Object(answer.getAnswer(),clazz);}));
        map.put("pageInfo",pageInfo);
        map.put("paperQuestionMap",paperQuestionMap);
        map.put("questions",questions);
        map.put("queVoMaps",queVoMaps);
        map.put("aVoMaps",aVoMaps);
        return map;
    }

//    private void getDXFourPub(PageInfo pageInfo){
//        //paper和question的关联表记录list
//        List<TkRPaperQuestion> paperQuestions=pageInfo.getList();
//        //paperQuestion的map
//        Map<Integer,TkRPaperQuestion> paperQuestionMap=paperQuestions.parallelStream().collect(Collectors.toConcurrentMap(TkRPaperQuestion::getQuestionId,paperQuestion->paperQuestion));
//        List<Integer> questionIds=new Vector<Integer>();
//        THREAD_LOCAL.set(paperQuestions);
//
//     }


    @Override
    public PageInfo<GetStuFourCQAResp> getStuFourCQA(GetStuQAReq req) {
        Map<String,Object> map=getPub(req,TkQuestion4CRespVo.class,QUESTION_TYPE_FOURC);
        List<TkQuestions> questions= (List<TkQuestions>) map.get("questions");
        Map<Integer,TkRPaperQuestion> paperQuestionMap= (Map<Integer, TkRPaperQuestion>) map.get("paperQuestionMap");
        Map<Integer,TkQuestion4CRespVo> queVoMaps= (Map<Integer, TkQuestion4CRespVo>) map.get("queVoMaps");
        Map<Integer, TkQuestion4CRespVo> aVoMaps= (Map<Integer, TkQuestion4CRespVo>) map.get("aVoMaps");
        PageInfo<TkRPaperQuestion> pageInfo= (PageInfo<TkRPaperQuestion>) map.get("pageInfo");

        List<GetStuFourCQAResp> resps=new Vector<>();
        questions.parallelStream().forEach(
                question->{
                    GetStuFourCQAResp resp=new GetStuFourCQAResp(paperQuestionMap.get(question.getId()),aVoMaps.get(question.getId()),queVoMaps.get(question.getId()));
                    resps.add(resp);
                }
        );
        return new PageInfoExt(pageInfo,resps);
    }


}
